package com.demo.core.utils;

import cn.hutool.core.util.ObjectUtil;
import lombok.NoArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.lang.Nullable;

import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @author Tan-Bowen
 * @description TODO spring上下文
 * @date 2021/7/22 16:06
 */
@NoArgsConstructor
public abstract class SpringContext {

    private static ApplicationContextHolder contextHolder;

    public static ApplicationContext context() {
        return getApplicationContext();
    }

    public static <T> T context(Function<ApplicationContext, T> function) {
        return function.apply(context());
    }

    public static void context(Consumer<ApplicationContext> consumer) {
        consumer.accept(context());
    }

    private static ApplicationContext getApplicationContext() {
        if (ObjectUtil.isAllEmpty(contextHolder, contextHolder.applicationContext)) {
            throw new IllegalStateException(String.format("%s 未注入, 请检查 %s 是否已注入.",
                    ApplicationContextAware.class.getName(), ApplicationContextHolder.class.getName()));
        }
        return contextHolder.applicationContext;
    }

    /**
     * @author Tan-Bowen
     * @description TODO 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicationContext
     * @date 2021/7/22 16:07
     */
    public static class ApplicationContextHolder implements ApplicationContextAware {

        private ApplicationContext applicationContext;

        /**
         * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
         */
        public void setApplicationContext(@Nullable ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
            SpringContext.contextHolder = this;
        }

    }
}
